package com.ly.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ly.common.StatusEnum;
import com.ly.dao.MenuDao;
import com.ly.dao.RoleMenuDao;
import com.ly.entity.Menu;
import com.ly.entity.RoleMenu;
import com.ly.exp.ServiceException;
import com.ly.rep.PageRequest;
import com.ly.service.MenuService;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class MenuServiceImpl implements MenuService {
    @Resource
    private MenuDao menuDao;
    @Resource
    private RoleMenuDao roleMenuDao;
    @Override
    public PageInfo<Menu> queryByPage(PageRequest<Menu> pageRequest) {
        PageHelper.startPage(pageRequest.getPageNum(),pageRequest.getPageSize());
        List<Menu> menuList = menuDao.selectAll(pageRequest.getQ());
        PageInfo<Menu> menuPageInfo = new PageInfo<>(menuList);
        return menuPageInfo;
    }

    @Override
    public void addMenu(Menu menu) {
        //判断子菜单内容的传递是否符合规范
        matching(menu);
        //判断数据库里面是否存在相同的菜单名称
        Menu queryMenu = new Menu();
        queryMenu.setMenuName(menu.getMenuName());
        Menu menuNameData = menuDao.queryByAll(queryMenu);
        if(Objects.nonNull(menuNameData)){
            throw  new ServiceException(StatusEnum.ERROR.getCode(), "该菜单已存在，不允许新增");
        }
        menuDao.insert(menu);
    }

    private void matching(Menu menu) {
        //代表此次新增的菜单是一个子菜单,同时父菜单必须选择
        if(menu.getParentId()!= null){
            if(!StringUtils.hasText(menu.getFilePath())){
                throw  new ServiceException(StatusEnum.ERROR.getCode(), "请填写Vue文件所在位置");
            }
            if(!StringUtils.hasText(menu.getPath())){
                throw  new ServiceException(StatusEnum.ERROR.getCode(), "请填写跳转路径");
            }
            if(!StringUtils.hasText(menu.getName())){
                throw  new ServiceException(StatusEnum.ERROR.getCode(), "请填写路由名称");
            }
            //查询该parentId的数据 是否 还包含parentId  子菜单层级 我只限定2层
            Menu upMenu = menuDao.selectById(menu.getParentId());
            if(Objects.isNull(upMenu)){
                throw  new ServiceException(StatusEnum.ERROR.getCode(), "父菜单不能为空");
            }
            if(upMenu.getParentId() != null){
                throw  new ServiceException(StatusEnum.ERROR.getCode(), "只允许新增2层菜单");
            }
        }
    }

    @Override
    public void delMenu(Integer menuId) {
        //1.判断菜单是否存在
        Menu menu = menuDao.selectById(menuId);
        if(Objects.isNull(menu)){
            throw  new ServiceException(StatusEnum.ERROR.getCode(), "找不到该菜单");
        }
        List<Integer> delIds = new ArrayList<>();
        delIds.add(menuId);
        //2.判断是不是父菜单  父菜单=>parentId==null
        if(menu.getParentId() == null){
            Menu menuQuery = new Menu();
            menuQuery.setParentId(menuId);
            //查询父菜单下面的所有子菜单，删除父菜单，当然要把所有子菜单一起删除
            List<Menu> menus = menuDao.selectAll(menuQuery);
            if(!CollectionUtils.isEmpty(menus)){
                delIds.addAll(menus.stream().map(Menu::getId).distinct().collect(Collectors.toList()));
            }
        }
        //3.删除菜单
        menuDao.delBatchByIds(delIds);
        //4.删除菜单与角色的关联
        RoleMenu roleMenuQuery = new RoleMenu();
        roleMenuQuery.setMenuIds(delIds);
        List<RoleMenu> roleMenus = roleMenuDao.selectAll(roleMenuQuery);
        if(!CollectionUtils.isEmpty(roleMenus)){
            roleMenuDao.delBatchByIds(roleMenus.stream().map(RoleMenu::getId).distinct().collect(Collectors.toList()));
        }
    }

    @Override
    public List<Menu> menuList() {
        //1.查询所有的菜单
        List<Menu> menuList = menuDao.queryAll();
        //2.帅选出所有的父菜单
        List<Menu> parentMenus = menuList.stream().filter(menu -> menu.getParentId() == null).collect(Collectors.toList());
        //3.循环所有的父菜单
        for(Menu parentMenu:parentMenus){
            recursionMenu(parentMenu,menuList);
        }
        //4.排序数据
        parentMenus = parentMenus.stream().sorted(Comparator.comparing(Menu::getSort)).collect(Collectors.toList());
        return parentMenus;
    }
    /**
     *   递归所有的子菜单
     */
    private void recursionMenu(Menu parentMenu, List<Menu> menus) {
        //1.拿到父菜单下面的所有子菜单
        List<Menu> childrenList = menus.stream()
                .filter(u -> u.getParentId() != null)
                .filter(u -> u.getParentId().compareTo(parentMenu.getId()) == 0)
                .collect(Collectors.toList());
        parentMenu.setChildren(childrenList);
        for (Menu childrenMenu : childrenList){
            recursionMenu(childrenMenu,menus);
        }
    }



    @Override
    public List<Menu> menuListByRoleName(String roleName) {
        return null;
    }
}
